package tree

import "fmt"

/**
	Go语言仅支持封装， 不支持继承和多态
	没有 class， 只有 struct(结构)

	没有构造方法, 如果需要可以定义工厂函数

	值接收者VS指针接收者
	结构体修改内容用指针接收者，不修改内容用值接收者
	结构体很大那么建议使用接收者，因为值传递代表着值拷贝

 */

 // 定义一个结构体
type TreeNode struct {
	// 整型
	Value int

	// TreeNode类型，但是必须是指针
	Left, Right *TreeNode
}

// 给 结构定义 方法
// (node TreeNode) 称为 接收者, 表示这个方法是给 TreeNode这个结构用的
// (node TreeNode) 这个地方是值传递，不是引用传递，除非指针 (node *TreeNode)
// root 表示 TreeNode, 然后调用 root.print()
func (node TreeNode) print()  {
	fmt.Println(node)
}

func (node *TreeNode) setValue(val int)  {
	if node == nil {
		fmt.Println("nil 不能设置值！")
		return
	}

	node.Value = val
}

// 遍历
func (node *TreeNode) trease() {
	if node == nil {
		return
	}

	// 为什么此处的调用 left 或者 right 不用判断 是否为 nil？
	/**
		因为nil也可以作为参数传递, 也就是调用了 left 后，此时是个 nil，nil也是一个值，
		只是我的值为nil而已，此时的nil也可以代表我TreeNode本身，nil在Go预压里面是有意义的，
		这个时候在调用 trease() 方法时在去把 TreeNode 传递过去!
	 */

	node.Left.trease()
	node.Right.trease()
}

// 工厂函数,
// 返回的是局部变量的地址
func createTreeNode(val int) *TreeNode {
	return &TreeNode{Value: val}
}


func main() {

	// 声明一个 TreeNode 的类型的变量
	// 不会分配内存
	var root TreeNode

	// 创建一个 TreeNode， 并且赋值给 root
	// TreeNode{value: 3} 表示创建的时候给 value 字段赋一个值
	root = TreeNode{Value: 3}
	// 给 TreeNode 里面的 left 字段赋值，并且是一个指针
	root.Left = &TreeNode{}
	root.Right = &TreeNode{4, nil, nil}

	// make() 只用于映射、切片和程道，不返回指针。要明确的得到指针用 new() 分配
	// new() 创建的同时，可以得到指针
	// 表示把 root里面 right 里面的 left 赋值
	root.Right.Left = new(TreeNode)
	
}
